package com.ei.itop.daemon.job;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.annotation.Resource;
import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.search.AndTerm;
import javax.mail.search.ComparisonTerm;
import javax.mail.search.SearchTerm;
import javax.mail.search.SentDateTerm;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.htmlparser.Parser;
import org.htmlparser.visitors.TextExtractingVisitor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.ailk.dazzle.util.sec.Encrypt;
import com.ailk.dazzle.util.type.DateUtils;
import com.ei.itop.common.bean.MailMessage;
import com.ei.itop.incidentmgnt.bean.TransactionMailMessage;
import com.ei.itop.incidentmgnt.service.TransactionService;

@Component
public class MailReceiveJob {

	private static final Logger log = Logger.getLogger(MailReceiveJob.class);

	@Resource(name = "mailReceiveConfig")
	Map<String, String> mailReceiveConfig;
	
	@Autowired
	TransactionService transactionService;

	// 每1分钟尝试获取support邮箱的邮件
	@Scheduled(cron = "0 0/1 * * * ?")
	void work() {
		//获取当前时间
		Date  curDate = new Date();
		//如果禁用了接收，则不进行邮件收取及处理
		if ("false".equals(mailReceiveConfig.get("mail.allowed"))) {
			return;
		}
		//格式化时间
		DateFormat df1 = new SimpleDateFormat("yyyyMMddHHmm");
		DateFormat df2 = new SimpleDateFormat("yyyyMMddHHmmsss");
		//邮箱存储
		Store store = null;
		//收件箱
		Folder folder = null;
		try {
			//查询开始时间
			Date qEndDate = df2.parse(df1.format(curDate)+"000");
			//查询结束时间
			Date qStartDate = DateUtils.dateOffset(qEndDate, Calendar.MINUTE, -1);
			// 创建一个有具体连接信息的Properties对象
			Properties props = new Properties();
			props.setProperty("mail.store.protocol", "pop3");
			props.setProperty("mail.pop3.host", mailReceiveConfig.get("mail.host"));
			// 使用Properties对象获得Session对象
			Session session = Session.getInstance(props);
			session.setDebug(false);
			// 利用Session对象获得Store对象，并连接pop3服务器
			store = session.getStore();
			store.connect(mailReceiveConfig.get("mail.host"), mailReceiveConfig.get("mail.username"),
					Encrypt.decrypt(mailReceiveConfig.get("mail.password")));
			// 获得邮箱内的邮件夹Folder对象，以"读-写"打开
			folder = store.getFolder("INBOX");		
			folder.open(Folder.READ_ONLY);
			// 搜索该时间段内的所有邮件 EQ（＝）、GE（>=）、GT（>）、LE（<=）、LT（<）、NE（!=）
			SearchTerm st = new AndTerm(new SentDateTerm(ComparisonTerm.GE, qStartDate),
					new SentDateTerm(ComparisonTerm.LT, qEndDate));
			Message[] messages = folder.search(st);
			int mailCounts = messages.length;
			log.info("("+qStartDate+"~"+qEndDate+")共收到" + mailCounts + "封回复的邮件！");
			List<MailMessage> packedMsg = new ArrayList<MailMessage>();
			for (int i = 0; i < mailCounts; i++) {
				String subject = messages[i].getSubject();
				//并非回复给itop的邮件
				if(subject.indexOf("[ITOP]")==-1){
					continue;
				}	
				MailMessage mm = new MailMessage();
				mm.setSubject(subject);
				String from = (messages[i].getFrom()[0]).toString();
				if(from.contains("<")){
					int startIndex = from.indexOf("<");
					int endIndex = from.indexOf(">", startIndex);
					mm.setFrom(from.substring(startIndex+1, endIndex));
				}else{
					mm.setFrom(from);
				}
				Object msgContent = messages[i].getContent();
				if(msgContent instanceof Multipart){
					BodyPart bp = ((Multipart)msgContent).getBodyPart(0);
					mm.setContentType(bp.getContentType());
					mm.setContent(bp.getContent().toString());
				}else{
					mm.setContentType(messages[i].getContentType());
					mm.setContent((String)msgContent.toString());
				}
				packedMsg.add(mm);
				//POP3不支持删除，imap支持，后续如果改为imap协议收件，则放开此处代码
//				messages[i].setFlag(Flags.Flag.DELETED, true);
//				messages[i].saveChanges();
			}
			//处理邮件
			if(packedMsg.size()>0){
				messageAutoCommit(packedMsg);
			}
		} catch (Exception e) {
			log.error("自动收取邮件处理失败",e);
		} finally{
			// 关闭连接时设置了删除标记的邮件才会被真正删除，相当于"QUIT"命令
			try {
				if(folder!=null){
					folder.close(false);
				}
				if(store!=null){
					store.close();
				}
			} catch (Exception e) {
				log.error("关闭邮箱连接失败",e);
			}
		}
	}
	
	public void messageAutoCommit(final List<MailMessage> packedMsg){
		//启动线程，异步处理，防止处理不完下一时刻收取邮件又到达
		new Thread(){
			public void run() {
				List<TransactionMailMessage> commitMsg = new ArrayList<TransactionMailMessage>();
				//解析消息，将事件内容结构化
				for(MailMessage mm:packedMsg){
					//如果不包含事件编号，则不处理
					if(mm.getSubject().indexOf("[No.")==-1){
						continue;
					}
					TransactionMailMessage tm = new TransactionMailMessage();
					//取得发件人账号
					tm.setUserAccount(mm.getFrom());
					int startIndex = mm.getSubject().indexOf("[No.")+4;
					int endIndex = mm.getSubject().indexOf("]", startIndex);
					//取得事件编号
					tm.setIncidentNo(mm.getSubject().substring(startIndex, endIndex));
					//取得事件内容
					try {
						if(mm.getContentType().contains("text/plain")){
							//以第一个空行为界限，截掉后面的内容
							String content = mm.getContent();
							String[] lines = content.split("\r\n");
							int index = 0;
							for(int i=0;i<lines.length;i++){
								if("".equals(lines[i].trim())){
									index = i;
									break;
								}
							}
							tm.setTransContent(StringUtils.join(ArrayUtils.subarray(lines, 0, index),""));
						}else if(mm.getContentType().contains("text/html")){
							Parser parser = new Parser();
							//qq邮箱
							if(mm.getContent().contains("<span class=\"mail-footer\">")){
								parser.setInputHTML(mm.getContent().substring(0, mm.getContent().indexOf("<span class=\"mail-footer\">")));
							}
							//网易邮箱大师
							else if(mm.getContent().contains("<div id=\"contentDescription\"")){
								int subStart = mm.getContent().indexOf("<div id=\"contentDescription\"");
								int subEnd = mm.getContent().indexOf("<div class=\"NETEASEMAILMASTERLOCALSIGNATURE\">");
								parser.setInputHTML(mm.getContent().substring(subStart,subEnd));
							}
							//其他邮箱，先按照全量存入处理，不过有点粗暴，暂时未想到好的办法
							else{
								parser.setInputHTML(mm.getContent());
							}
							TextExtractingVisitor visitor = new TextExtractingVisitor();
							parser.visitAllNodesWith(visitor);
							String text = visitor.getExtractedText();
							tm.setTransContent(text);
						}else{
							//以第一个空行为界限，截掉后面的内容
							String content = mm.getContent();
							String[] lines = content.split("\r\n");
							int index = 0;
							for(int i=0;i<lines.length;i++){
								if("".equals(lines[i].trim())){
									index = i;
									break;
								}
							}
							tm.setTransContent(StringUtils.join(ArrayUtils.subarray(lines, 0, index),""));
						}
					} catch (Exception e) {
						log.error("解析邮件正文出错",e);
					}
					if(StringUtils.isNotEmpty(tm.getTransContent())){
						commitMsg.add(tm);
					}
				}
				if(commitMsg.size()>0){
					transactionService.MBLAutoCommitTransaction(commitMsg);
				}
			}
		}.start();
	}
	
	public static void main(String[] args) throws Exception {
		String test = "abc\r\nfdsaf\r\n";
		System.out.println(test.replaceAll("\r\n", ""));
		//		System.out.println(visitor.getExtractedText());
	}
	
	public static void main2(String[] args) {
		String test = "[ITOP][No.fafdasfdsaf-123123afdfa123]thank you for your regist!";
		int startIndex = test.indexOf("[No.")+4;
		int endIndex = test.indexOf("]", startIndex);
		System.out.println(test.substring(startIndex, endIndex));
	}

}
